#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "wav.h"
#include <alsa/asoundlib.h>
#include <math.h>
/// @brief 声音应用程序操作流程 读取音频文件信息->打开音频设备文件->设置音频设备参数->读/写直到结束-》关闭设备
/// @return
int main()
{
    // 步骤1：读取音频文件信息
    FILE *file = fopen("/home/bzsg/workspace/study/linuxc/assets/test.wav", "rb");
    if (!file)
    {
        perror("Error opening file");
        return 1;
    }

    // 读取文件头
    RIFFHeader riff;
    FmtHeader fmt;
    DataHeader data;

    if (fread(&riff, sizeof(RIFFHeader), 1, file) != 1)
    {
        perror("Error reading RIFF header");
        fclose(file);
        return 1;
    }

    // 验证RIFF头
    if (strncmp(riff.chunkID, "RIFF", 4) != 0 ||
        strncmp(riff.format, "WAVE", 4) != 0)
    {
        printf("Invalid WAV file\n");
        fclose(file);
        return 1;
    }

    // 读取fmt块
    if (fread(&fmt, sizeof(FmtHeader), 1, file) != 1)
    {
        perror("Error reading fmt header");
        fclose(file);
        return 1;
    }

    // 验证fmt块
    if (strncmp(fmt.subchunkID, "fmt ", 4) != 0)
    {
        printf("Invalid fmt chunk\n");
        fclose(file);
        return 1;
    }

    // 读取data块头
    if (fread(&data, sizeof(DataHeader), 1, file) != 1)
    {
        perror("Error reading data header");
        fclose(file);
        return 1;
    }

    // 验证data块头
    if (strncmp(data.dataID, "data", 4) != 0)
    {
        printf("data chunk\n");
        fclose(file);
        return 1;
    }

    printfWav(&riff, &fmt, &data);
    // 步骤2：打开音频设备文件
    snd_pcm_t *pcm_handle;
    snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0);

    // 步骤3：设置音频设备参数
    //  配置硬件参数
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_hw_params_alloca(&hw_params);
    snd_pcm_hw_params_any(pcm_handle, hw_params);

    // 设置关键参数
    snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
    snd_pcm_hw_params_set_format(pcm_handle, hw_params,
                                 (fmt.bitsPerSample == 16) ? SND_PCM_FORMAT_S16_LE : SND_PCM_FORMAT_S24_LE); // 设置位深度
    snd_pcm_hw_params_set_channels(pcm_handle, hw_params, fmt.numChannels);                                  // 设置声道数
    snd_pcm_hw_params_set_rate(pcm_handle, hw_params, fmt.sampleRate, 0);                                    // 设置采样率

    // 应用参数
    snd_pcm_hw_params(pcm_handle, hw_params);

    // 步骤4：读/写直到结束
    //  读取并播放音频数据
    const int buffer_size = 4096;
    uint8_t buffer[buffer_size];
    size_t bytes_remaining = data.dataSize;

    while (bytes_remaining > 0)
    {
        size_t read_size = fmin(buffer_size, bytes_remaining);
        fread(buffer, 1, read_size, file);

        // 写入ALSA缓冲区
        snd_pcm_sframes_t frames = snd_pcm_writei(pcm_handle, buffer,
                                                  read_size / (fmt.bitsPerSample / 8 * fmt.numChannels));

        if (frames < 0)
            frames = snd_pcm_recover(pcm_handle, frames, 0); // 处理欠载

        bytes_remaining -= read_size;
    }
    // 步骤5：关闭设备
    snd_pcm_drain(pcm_handle); // 等待播放完成
    snd_pcm_close(pcm_handle);
    fclose(file);
    return 0;
}